package com.ruoyi.system.controller;

import com.ruoyi.common.json.JSONObject;
import com.ruoyi.framework.web.domain.server.Sys;
import com.ruoyi.system.domain.SysAlarm;
import com.ruoyi.system.domain.SysConfiguration;
import com.ruoyi.system.domain.SysDevice;
import com.ruoyi.system.domain.SysHeartbeart;
import com.ruoyi.system.domain.rsu.MessageHeartbeat;
import com.ruoyi.system.domain.rsu.MessageReport;
import com.ruoyi.system.domain.rsu.OtaCommand;
import com.ruoyi.system.service.ISysAlarmService;
import com.ruoyi.system.service.ISysConfigurationService;
import com.ruoyi.system.service.ISysDeviceService;

import com.ruoyi.system.service.ISysHeartbeartService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

class query{
    public String deviceId;
    public Long timeStamp;
}

/**
 * @author RHH
 */

@Slf4j
@Controller
@RequestMapping(value = "/rsu")
public class RsuController {
    @Autowired
    private final ISysAlarmService sysAlarmService;

    @Autowired
    private final ISysDeviceService deviceService;

    @Autowired
    private final ISysConfigurationService sysConfigurationService;

    private final RedisTemplate<String, String> redisTemplate;
    @Autowired
    private final ISysHeartbeartService sysHeartbeartService;

    @Autowired
    RsuController(RedisTemplate<String, String> redisTemplate, ISysAlarmService sysAlarmService, ISysDeviceService deviceService, ISysConfigurationService sysConfigurationService, ISysHeartbeartService sysHeartbeartService) {
        this.redisTemplate = redisTemplate;
        this.sysAlarmService=sysAlarmService;
        this.deviceService = deviceService;
        this.sysConfigurationService = sysConfigurationService;
        this.sysHeartbeartService = sysHeartbeartService;
        //初始化otaNeedUpdate
        redisTemplate.opsForValue().set("otaNeedUpdate", "0");
    }

    /**
     * 1设备在线心跳 功能：由RSU设备周期性的向RSU管理平台上传在线心跳。/
     * 记录设备  在线/离线   （在线离线的标准// 每30sf发送一次消息）
     */
    @PostMapping(value = "/message_heartbeat")
    @ResponseBody
    public String heartbeatReport(@RequestBody MessageHeartbeat messageHeartbeat) {
//        try {
//            //在redis中记录rsu在线状态,有效期10min
//
//            redisTemplate.opsForHash().put("online", messageHeartbeat.getDeviceId(), "1");
//            redisTemplate.expire("online", 3, TimeUnit.MINUTES);
//        } catch (Exception e) {
//            log.debug(e.toString());
//            return responseTemplate(400);
//        }
//        return responseTemplate(200);
        try{
            SysHeartbeart sysHeartbeart=new SysHeartbeart();
            sysHeartbeart.setDeviceId(messageHeartbeat.getDeviceId());
            sysHeartbeart.setTimeStamp(messageHeartbeat.getTimeStamp());
            System.out.println(sysHeartbeart);
            if(sysHeartbeartService.selectSysHeartbeartById(messageHeartbeat.getDeviceId())!=null){
                sysHeartbeartService.updateSysHeartbeart(sysHeartbeart);
            }else{
                sysHeartbeartService.insertSysHeartbeart(sysHeartbeart);
            }

        }catch (Exception e){
            e.printStackTrace();
            return responseTemplate(400);
        }
        return responseTemplate(200);
    }
    @RequestMapping(value = "/download/{deviceId}/{downloadType}/{fileName}")
    @ResponseBody
    public ResponseEntity<byte[]> download(@PathVariable("deviceId")String deviceId,@PathVariable("downloadType")String type,@PathVariable("fileName")String fileName){
        try{
            String path="ftp://ftpuser:zdx19981006@150.158.176.170:21/RSU_DATA/"+deviceId+"/"+type+"/"+fileName;
            byte[] bytes = FileUtils.readFileToByteArray(new File(path));
            HttpHeaders headers=new HttpHeaders();
            headers.set("Content-Disposition","attachment;filename="+fileName);
            ResponseEntity<byte[]> entity=new ResponseEntity<>(bytes,headers, HttpStatus.OK);
            return entity;
        } catch (IOException e) {
            System.out.println("下载出错");
            return null;
        }
    }
    /**
     * 2设备状态上报 功能：由RSU设备周期性的向RSU管理平台上传RSU设备的设备信息
     */
    @PostMapping(value = "/message_report")
    @ResponseBody
    public String messageReport(@RequestBody MessageReport messageReport) {
        try {
            SysDevice sysDevice = new SysDevice();
            sysDevice.setDeviceId(messageReport.getDeviceId());
            sysDevice.setDeviceRunTime(messageReport.getRun_time());
            sysDevice.setDeviceLat(messageReport.getLat());
            sysDevice.setDeviceLng(messageReport.getLng());
            sysDevice.setDeviceElevation(messageReport.getElevation());
            sysDevice.setDeviceCupOcRate(messageReport.getCpu_oc_rate());
            sysDevice.setDeviceMemOcRate(messageReport.getMem_oc_rate());
            sysDevice.setDeviceVersion(messageReport.getVersion());
            sysDevice.setDeviceTimestamp(System.currentTimeMillis());
            //@Todo:sysDevice需要改ErrorRate
            sysDevice.setDeviceErrorRate(messageReport.getError_rate()[0]);
            System.out.println(sysDevice);
            //判断在线离线
            SysHeartbeart sysHeartbeart = sysHeartbeartService.selectSysHeartbeartById(messageReport.getDeviceId());
            Long currentTime;
            Long lastTime;
            currentTime= System.currentTimeMillis();
            lastTime=sysHeartbeart.getTimeStamp();
            int time1=(int)(currentTime-lastTime)/(1000*60);

            if(time1>1){
                sysDevice.setDeviceStatus("1");
            }else{
                sysDevice.setDeviceStatus("0");
            }
            if(deviceService.selectSysDeviceById(messageReport.getDeviceId())!=null){
                deviceService.updateSysDevice(sysDevice);
            }

            else {
                deviceService.insertSysDevice(sysDevice);
            }


            //获取发送的成功率 如果失败率高，则发出警告
            Double deviceErrorRate = sysDevice.getDeviceErrorRate();
            if(deviceErrorRate>90.0){
                SysAlarm sysAlarm = new SysAlarm();
                //SysAlarm sysAlarm=sysAlarmService.selectSysAlarmById(messageReport.getDeviceId());
                sysAlarm.setAlarmDeviceId(messageReport.getDeviceId());
                Long timestamp=System.currentTimeMillis();
                sysAlarm.setAlarmTimestamp(timestamp+"");
                sysAlarm.setAlarmInfo("失败率高");
                sysAlarm.setAlarmStatus("0");
                sysAlarmService.insertSysAlarm(sysAlarm);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.debug(e.toString());
            return responseTemplate(400);
        }
        return responseTemplate(200);
    }

    /**
     * 3:配置更新查询 功能：RSU设备向RSU管理网站周期性的发起配置是否更新的查询请求，RSU管理网站返回相应信息。
     * @RequestParam("deviceId") String deviceId, @RequestParam("timeStamp") long timeStamp
     */
    @RequestMapping(value = "/config_query", method = RequestMethod.GET)
    @ResponseBody
    public String configQuery(@RequestBody query q) {
//        if(q.deviceId==""){
//            q.deviceId="0";
//        }
        String deviceId=q.deviceId;
        Long timeStamp=q.timeStamp;
        System.out.println(deviceId);
        SysConfiguration sysConfiguration = null;
//        ISysConfigurationService configurationService = new SysConfigurationServiceImpl();
        try {
            //从数据库查询
            sysConfiguration = sysConfigurationService.selectSysConfigurationById(deviceId);
        } catch (Exception ignored) {
            ignored.printStackTrace();
        }
        if (sysConfiguration == null) {
            System.out.println("start");
            System.out.println(responseTemplate(400));
            System.out.println("end");
            return responseTemplate(400);
        } else {
            String temp=  sysConfiguration.toResponse();

//            if(sysConfiguration.getConfigurationMapneedupdate().equals(1)){
//                sysConfiguration.setConfigurationMapneedupdate(0);
//            }
//            if(sysConfiguration.getConfigurationSpatneedupdate().equals(1)){
//                sysConfiguration.setConfigurationSpatneedupdate(0);
//            }
//            if(sysConfiguration.getConfigurationRsineedupdate().equals(1)){
//                sysConfiguration.setConfigurationRsineedupdate(0);
//            }
            //查询心跳表
            SysHeartbeart sysHeartbeart =null;

            sysHeartbeart = sysHeartbeartService.selectSysHeartbeartById(deviceId);
            Long lastTime;
            Long currentTime;
            if(sysHeartbeart==null){
                lastTime=0L;
                currentTime=0L;
            } else{
            lastTime =sysHeartbeart.getTimeStamp();
            currentTime= System.currentTimeMillis();
            }
            System.out.println(currentTime);
            //将时间差转化为分钟
            int time=(int)(currentTime-lastTime)/(1000*60);
            //如果两条消息时间差大于三分钟将设备状态改为离线
            if(time>1){
                //0在线1离线
                SysDevice sysDevice=new SysDevice();
                sysDevice.setDeviceStatus("1");
            }
            sysConfigurationService.updateSysConfiguration(sysConfiguration);
            System.out.println(temp);
            return temp;
        }
    }

    /**
     * 4:命令查询 功能：RSU周期性的向RSU管理网站发起命令查询，如果有新命令，RSU将执行命令 方法：GET
     * 只返回最新数据
     */

    //向我查询，是不是有什么命令需要处理。 我返回
    @RequestMapping(value = "/command_query", method = RequestMethod.GET)
    @ResponseBody
    public String commandQuery(@RequestBody query q) {
        try {
//            String newCommand = (String) redisTemplate.opsForHash().get("command", deviceId);
            JSONObject commandRefreshRet = new JSONObject();
            commandRefreshRet.put("timeStamp", System.currentTimeMillis());

            SysAlarm alarm=new SysAlarm();


            List<SysAlarm> sysAlarmList =sysAlarmService.selectSysAlarmList(alarm);
            for(int i=0;i<sysAlarmList.size();i++){
                if(sysAlarmList.get(i).getAlarmDeviceId().equals(q.deviceId)){
                    //1已处理   0未处理
                    if(sysAlarmList.get(i).getAlarmSolution()!=null&&sysAlarmList.get(i).getAlarmStatus().equals("0")){
                       String  solution = sysAlarmList.get(i).getAlarmSolution();
                       if(solution.equals("0")){
                           commandRefreshRet.put("command", "REBOOT");
                       }
                        else{
                            commandRefreshRet.put("command","CONFIG_INITIAL");
                       }
                        String alarmId=sysAlarmList.get(i).getAlarmId();
                        sysAlarmService.deleteSysAlarmById(alarmId);
                        break;
                    }
                }
            }

            // commandRefreshRet.put("command", "REBOOT");
            //删除数据库中deviceId对应的命令信息。

//            String solution="REBOOT";
//            if(alarm==null){
//                solution="REBOOT";
//            }else {
//                solution = alarm.getAlarmSolution();
//            }


            return  commandRefreshRet.toString();
         //   return responseTemplate(200, commandRefreshRet.toString());
        } catch (Exception e) {
            log.debug(e.toString());
           // return responseTemplate(400);
            return "400";
        }
    }

    /**
     * 5:OTA升级查询 功能：RSU周期性的向RSU管理网站发起OTA查询指令，如果需要OTA升级，RSU进入OTA 升级流程 方法：GET
     */
    @RequestMapping(value = "/OTA_query", method = RequestMethod.GET)
    @ResponseBody
    public String otaQuery(@RequestParam("deviceId") String deviceId, @RequestParam("timeStamp") long timeStamp) {
        try {
            String ota = redisTemplate.opsForValue().get("otaNeedUpdate");
            if (ota != null) {
                int otaNeedUpdate = Integer.parseInt(ota);
                if (otaNeedUpdate == 1) {
                    String otaCommand = new OtaCommand().toString();
                    return responseTemplate(200, otaCommand);
                }
            }
        } catch (Exception e) {
            return responseTemplate(400);
        }
        return responseTemplate(200, "");
    }

    /**
     * 报警
     * @param sysAlarm
     * @return
     */

    @RequestMapping(value = "/alert", method = RequestMethod.POST)
    @ResponseBody
    public String alert(@RequestBody SysAlarm sysAlarm) {
        try{
            System.out.println(sysAlarm.toString());
            sysAlarmService.insertSysAlarm(sysAlarm);
        }catch (Exception e){
            return responseTemplate(400, e.toString());
        }
        return responseTemplate(200);
    }

    public static String responseTemplate(int code) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", code);
        return jsonObject.toString();
    }

    public static String responseTemplate(int code, String data) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", code);
        jsonObject.put("data", data);
        return jsonObject.toString();
    }

}
